#ifndef CS_MESSAGE_H
#define CS_MESSAGE_H

#include <cstdint>
#include <string>
#include <array>
#include <boost\shared_ptr.hpp>

namespace cs
{
	class message;
	typedef uint16_t address;
	typedef boost::shared_ptr<message> message_handle;

	class message
	{
	public:
		enum {header_length = 10};
		typedef std::array<char, header_length> header_t;

		message();
		message(const message& msg);
		message(uint16_t id, address sender, address receiver);
		message(uint16_t id, address sender, address receiver, std::string payload);

		std::string serialize();
		operator std::string();

		uint16_t id() const;
		address sender() const;
		address receiver() const;
		size_t size() const;
		std::string get() const;
		void set(const std::string& payload);
		header_t& get_header();
		bool decode_header();

	private:
		size_t msg_size_;
		uint16_t id_;
		address sender_;
		address receiver_;
		
		header_t header_;
		std::string payload_;

		template<typename T>
		void decode(T& what, size_t start);

		void calculate_size();
		void encode_header();
		void encode_size();
		void encode_id();
		void encode_sender();
		void encode_receiver();
	};
	
	template<typename T>
	void message::decode(T& what, size_t start) 
	{
		what = 0;
		for (size_t i = start; i < sizeof(T) + start; ++i) {
			what = what * 256 + (header_[i]&0xff);
		}
	}
}

#endif